home *** CD-ROM | disk | FTP | other *** search
- #include "midi.h"
- /*
- Copright 1988, G.E.S. Consulting
-
- NORMAL MODE tutorial, RECORD and PLAY
- for those who like to do all the work themselves!
-
-
- NOTE:
- struct eventlist {
- struct event *f; ptr to first event on que
- struct event *c; ptr to current event on que
- struct event *l; ptr to last event on que
- }
- Library does NOT maintain (or have knowledge of) this structure.
- You are free to devise you own way to manage event lists if you wish.
- */
- main()
- {
- struct event *p,*op, *qp = (struct event *)0;
- unsigned char r,sr;/* running status storage for get_event and show_event */
- int count= 0, eventno = 0; /* counters for show_event */
-
- init_event_list(10); /* allocate 10000 events */
- mpu_init(); /* install driver */
-
- /* tell em how to stop */
-
- printf("Playback will begin when you hit middle C\n");
-
- /* initialize running status */
- r = 0;
- sr = 0;
-
- /* note MIDI_START is necessary to get mpu to actually do something
- the first time around. see tech manual p. 20 */
-
- mpu_control(START_RECORD|MIDI_START);
-
- /* while MPU is still talking */
-
- while(p = get_event(&r,10))
- {
- show_event(++eventno,&count,&sr,p); /* show em what they did */
-
- if (!qp) /* chain events together */
- {
- qp = p;
- op = p;
- }
- else
- {
- op->n = p;
- op = p;
- }
-
- /* test for middle c pressed */
-
- if (p->d.data[0] == 60 /* middle c */
- && ((p->status == 0 && r == 0x90) || p->status == 0x90))
- break; /* ON or OFF */ /* all done */
- }
-
- /* tell MPU to finish up */
-
- mpu_control(STOP_RECORD|MIDI_STOP);
-
- /* wait for END of DATA */
-
- while(p = get_event(&r,10))
- {
- show_event(++eventno,&count,&sr,p);
- op->n = p;
- op = p;
- if (p->tbyte < 240 && p->status == 0xfc) /* end of data */
- break;
- }
-
- /* reset running status */
-
- r = 0;
- /* tell MPU which tracks to play */
-
- active_tracks(TRACK_1);
- clear_play_counters();
-
- /* start playing */
-
- mpu_control(START_PLAY|MIDI_START);
- op = qp;
-
- /* satisy requests for data */
-
- while(p = get_event(&r,10))
- {
- show_event(++eventno,&count,&sr,p);
- if (p->tbyte == 255 && p->status >= 0xf0 && p->status <= 0xf7)
- {
- send_message(op);
- op = op->n;
- }
-
- /* check for end of track */
-
- if (p->tbyte == 255 && p->status == 0xfc) /* end of data */
- break;
- }
- mpu_control(STOP_PLAY|MIDI_STOP);
- reset_mpu();
- mpu_close();
- }
-
- /* a handy routine to make an event human readable */
-
- char *etab[] = {
- "Note Off ",
- "Note On ",
- "Key Pres ",
- "Cntrl Chg",
- "Program ",
- "Chan Pres",
- "Ptch Weel",
- "MIDI MARK"
- };
-
- /* Midi Message Length table */
-
- int ltab[] = {2,2,2,2,1,1,2,0};
- show_event(int eventno,int *rcount,unsigned char *running,struct event *p)
- {
- printf("Event %03d ", eventno);
- if (p->tbyte < 0xf0) /* MIDI MESSAGE OR MPU MARK */
- {
- int etype;
- int chan;
- if (!p->status)
- p->status = *running;
- else if (p->status < 0xf0)
- *running = p->status;
- etype = (p->status >> 4) & 7;
- if (etype == 1 && p->d.data[1] == 0)
- etype--;
- chan = (p->status & 7);
- *rcount += p->tbyte;
- printf("Timng (%02x) %3d ",p->tbyte,*rcount);
- printf("%s ",etab[etype]);
- switch(etype)
- {
- case 0:
- printf("Pitch (%03d) ",p->d.data[0]);
- break;
- case 1:
- printf("Pitch (%03d) Velocity (%03d) ",p->d.data[0],
- p->d.data[1]);
- break;
- case 2:
- printf("Pitch (%03d) Pressure (%03d) ",p->d.data[0],
- p->d.data[1]);
- break;
- case 3:
- printf("Number (%03d) Value (%03d) ",p->d.data[0],
- p->d.data[1]);
- break;
- case 4:
- printf("Number (%03d) ",p->d.data[0]);
- break;
- case 5:
- printf("Pressure (%03d) ",p->d.data[0]);
- break;
- case 6:
- printf("LSB (%03d) MSB (%03d) ",p->d.data[0],
- p->d.data[1]);
- break;
- case 7:
- switch(p->status)
- {
- case 0xf8:
- printf("NOP ");
- break;
- case 0xf9:
- *rcount = 0;
- printf("Measure End ");
- break;
- case 0xfc:
- printf("Data End ");
- break;
- default:
- printf("INVALID! ");
- }
- break;
- }
- }
- else /* MPU MESSAGE */
- {
- int chan = p->status & 7;
- int stat = p->status;
- printf("Timng (%02x) %3d ",0,*rcount);
- printf("MPU MESSAGE ");
- if (stat >= 0xf0 && stat <= 0xf7)
- printf("Data Request: Channel %1d :",chan);
- else switch(stat)
- {
- case 0xf8:
- *rcount += 240;
- printf("Timer Overflow");
- break;
- case 0xf9:
- printf("Conductor Data Request");
- break;
- case 0xfa:
- printf("Midi Start");
- break;
- case 0xfb:
- printf("Midi Continue");
- break;
- case 0xfc:
- printf("Midi Stop");
- break;
- case 0xfd:
- printf("CLOCK to HOST");
- break;
- case 0xfe:
- printf("ACK");
- break;
- case 0xff:
- {
- int i;
- printf("SYS EX DATA[");
- for (i = 0; i < p->dlen; i++)
- printf("%02x",p->dlen > 4 ? p->d.dptr[i] : p->d.data[i]);
- printf("]");
- }
- break;
- }
- }
- printf("\n");
- }
-